var mongoose = require('mongoose');
var Loc = mongoose.model('Location');
var getDistance = function(pointA,pointB){
    var pk = 180 / 3.14169;
    var a1 = pointA[1] / pk;
    var a2 = pointA[0] / pk;
    var b1 = pointB[1] / pk;
    var b2 = pointB[0] / pk;
    var t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
    var t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
    var t3 = Math.sin(a1) * Math.sin(b1);
    var tt = Math.acos(t1 + t2 + t3);
    return 6366 * tt;
};


var sendJsonResponse = function(res,status,content){
    res.status(status);
    res.json(content);
};

module.exports.locationsListByDistance = function(req,res){
    var lng = parseFloat(req.query.lng);
    var lat = parseFloat(req.query.lat);
    var point = [lng,lat];
    if((!lng && lng !== 0) || (!lat && lat !==0)) {
        sendJsonResponse(res,404,{message:"lng and lat query parameters are required"});
        return;
    }
    if(Math.abs(lng)>180 || (Math.abs(lat)) > 90) {
        sendJsonResponse(res,404,{message:"lng and lat query parameters are not correct."});
        return;
    }
    Loc
        .find()
        .select("coords name address rating facilities _id")
        .exec(function(err,results){
            var locations = [];
            function getSortFun(order, sortBy) {
                var ordAlpah = (order == 'asc') ? '>' : '<';
                return new Function('a', 'b', 'return a.' + sortBy + ordAlpah + 'b.' + sortBy + '?1:-1');
            }
            if(err) {
                sendJsonResponse(req,404,err);
            } else {
                results.forEach(function(doc){
                    var distance = getDistance(point,doc.coords);
                    if( distance < parseInt(req.query.maxDistance)) {
                        locations.push({
                            distance:distance,
                            name: doc.name,
                            address:doc.address,
                            rating:doc.rating,
                            facilities:doc.facilities,
                            _id:doc._id
                        })
                    }
                });
                locations.sort(getSortFun('asc', 'distance'));
                var data = locations.slice(0,10);
                sendJsonResponse(res,200,data);
            }
        });
};

module.exports.locationsCreate = function(req,res){
    console.log(req.body);
    Loc.create({
        name:req.body.name,
        address:req.body.address,
        facilities:req.body.facilities.split(","),
        coords:[parseFloat(req.body.lng),parseFloat(req.body.lat)],
        openingTime:[{
            days:req.body.days1,
            opening:req.body.opening1,
            closing:req.body.closing1,
            closed:req.body.closed1
        },{
            days:req.body.days2,
            opening:req.body.opening2,
            closing:req.body.closing2,
            closed:req.body.closed2
        }]
    },function(err,location){
        if(err){
            sendJsonResponse(res,400,err);
        }else {
            sendJsonResponse(res,201,location);
        }
    });
};

module.exports.locationsReadOne = function(req,res){
    if(req.params && req.params.locationid){
        Loc
            .findById(req.params.locationid)
            .exec(function(err,location){
                if(!location){
                    sendJsonResponse(res,404,{message:"locationid not found."});
                }else if (err){
                    sendJsonResponse(res,404,err);
                }else {
                    sendJsonResponse(res,200,location);
                }
            });
    }else {
        sendJsonResponse(res,200,{message:"No locationid in request."});
    }

};

module.exports.locationsUpdateOne = function(req,res){
    if(!req.params.locationid){
        sendJsonResponse(res,404,{message:"Not found, locationid is required"});
        return;
    }
    Loc
        .findById(req.params.locationid)
        .select("-reviews -rating")
        .exec(function(err,location){
            if(!location){
                sendJsonResponse(res,404,{message:"locationid not found"});
            }else if(err){
                sendJsonResponse(res,400,err);
            }
            if(req.body.name)location.name = req.body.name;
            if(req.body.address)location.address = req.body.address;
            if(req.body.facilities)location.facilities = req.body.facilities.split(",");
            if(req.body.lng&&req.body.lat)location.coords = [parseFloat(req.body.lng),parseFloat(req.body.lat)];
            if(req.body.days1){
                location.openingTime = [{
                    days:req.body.days1,
                    opening:req.body.opening1,
                    closing:req.body.closing1,
                    closed:req.body.closed1
                },{
                    days:req.body.days2,
                    opening:req.body.opening2,
                    closing:req.body.closing2,
                    closed:req.body.closed2
                }];
            }
            location.save(function(err,location){
                if (err) {
                    sendJsonResponse(res, 404, err);
                } else {
                    sendJsonResponse(res, 200, location);
                }
            });
        });
};
module.exports.locationsDeleteOne = function(req,res){
    var locationid = req.params.locationid;
    if(locationid){
        Loc
            .findByIdAndRemove(locationid)
            .exec(function(err,location){
                if(err){
                    sendJsonResponse(res,404,err);
                    return;
                }
                sendJsonResponse(res,204,null);
            });
    }else {
        sendJsonResponse(res,404,{message:"No locationid"});
    }
};